package com.qsd.TeacherSystem.exception;

import com.qsd.common.enums.ResultStatus;
import com.qsd.common.vo.BaseVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

@Slf4j
@RestControllerAdvice(basePackages = "com.qsd.TeacherSystem.controller")
public class GlobalExceptionHandler {

    /**
     * 处理自定义的业务异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = BizException.class)
    public BaseVo bizExceptionHandler(BizException e) {
        log.error("发生业务异常！原因是：{}", e.getErrorMsg());
        BaseVo baseVo = new BaseVo();
        baseVo.setCode(e.errorCode);
        baseVo.setMessage(e.getMessage());
        return baseVo;
    }

    /**
     * 处理空指针的异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = NullPointerException.class)
    public BaseVo exceptionHandler(NullPointerException e) {
        log.error("发生空指针异常！原因是:", e);
        BaseVo baseVo = new BaseVo();
        baseVo.setCode(ResultStatus.SYSTEM_ERROR.getCode());
        baseVo.setMessage(ResultStatus.SYSTEM_ERROR.getMessage());
        return baseVo;
    }


    @ExceptionHandler(ConstraintViolationException.class)
    public BaseVo handleConstraintViolationException(ConstraintViolationException ex){
        // 获取所有错误信息
        HashSet<ConstraintViolation<?>> set = (HashSet<ConstraintViolation<?>>) ex.getConstraintViolations();
        Iterator<ConstraintViolation<?>> iterator = set.iterator();
        BaseVo baseVo = new BaseVo();
        if (iterator.hasNext()) {
            ConstraintViolation<?> next = iterator.next();
            // 只取一个异常信息返回
            String msg = next.getMessageTemplate();
            //返回自定义信息格式
            baseVo.setMessage(msg);
            return baseVo;
        }
        baseVo.setMessage("参数错误");
        return baseVo;
    }


    /**
     * 参数校验异常
     *
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public BaseVo exceptionHandler(MethodArgumentNotValidException ex) {
        List<ObjectError> allErrors = ex.getBindingResult().getAllErrors();
        //只返回第一个信息
        ObjectError error = allErrors.get(0);
        BaseVo baseVo = new BaseVo();
        baseVo.setCode(error.getCode());
        baseVo.setMessage(error.getDefaultMessage());
        return baseVo;
    }


    /**
     * 处理其他异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public BaseVo exceptionHandler(Exception e) {
        log.error("未知异常！原因是:", e);
        BaseVo baseVo = new BaseVo();
        baseVo.setCode(ResultStatus.SYSTEM_ERROR.getCode());
        baseVo.setMessage(ResultStatus.SYSTEM_ERROR.getMessage());
        return baseVo;
    }

}
